#include <fstream>
#include <stdlib.h>
#include "dice.h"
#include "scoring.h"

/*--- Constructor ---*/
ScoreDice::ScoreDice()
{
	int t_count = 0;
	ifstream fIn;
	fIn.open("score.txt");

	score = new ScoreObj[MAX_ITEMS];
	for(int i = 0; i < MAX_ITEMS; i++){
		score[i].beenScored = false;
		score[i].score = 0;
		score[i].scoreTypes = (ScoreType)i;
		getline(fIn,score[i].name,'\n');
	}
	fIn.close();
}

/*--- Base Game Functions ---*/
void ScoreDice::update(Dice * dice, Position a_position, SDL_Surface * a_buffer)
{
	int tX,tX2,tY,tY2;
	tX = tX2 = tY = tY2 = 0;
	if((a_position.y > 0 && a_position.y < (text_height * MAX_ITEMS)) &&
		(a_position.x > (a_buffer->w - MAX_TEXT_WIDTH) && a_position.x < a_buffer->w)){
			for(int j = 0; j < MAX_ITEMS; j++){
				tX = (a_buffer->w - MAX_TEXT_WIDTH);
				tX2 = tX + getTextWidth(j);
				tY = text_height * j;
				tY2 = text_height * (j+1);
				if((a_position.x > tX && a_position.x < tX2) &&
					(a_position.y > tY && a_position.y < tY2)){
						switch(j)
						{
						case 0: // fall through - case bracket
						case 1: // for proper case;
						case 2:
						case 3:
						case 4:
						case 5:
						case 6:
						case 7:
						case 8:
						case 9:
						case 10:
						case 11:
						case 12:
							// ! == score this item
							if(!score[j].beenScored)
								setScores(j,dice);
							break;
						}
				}
			}
	}
}

void ScoreDice::draw(SDL_Surface *a_buffer)
{
	char* t_score = new char[MAX_TEXT_WIDTH];
	SDL_Color color = {255,0,0};

	SDL_Rect rect = {0,0,0,0};
	// this prints out the text for the scoreObj 
	for(int i = 0; i < MAX_ITEMS; i++){
		SDL_Surface * text_surface;
		text_surface = TTF_RenderText_Solid(font, score[i].name.c_str(), color);
		rect.w = MAX_TEXT_WIDTH;
		rect.h = text_surface->h;
		score[i].text_width = text_surface->w;
		drawTile(text_surface, &rect, 0, a_buffer, (a_buffer->w - rect.w), i*text_surface->h);
		_itoa(score[i].score,t_score,10);
		text_surface = TTF_RenderText_Solid(font, t_score, color);
		rect.w = text_surface->w;
		drawTile(text_surface, &rect, 0, a_buffer, (a_buffer->w - (rect.w + MAX_TEXT_WIDTH)), i*text_surface->h);
		// frees the surface not in use.
		SDL_FreeSurface(text_surface);
	}
}

void ScoreDice::release()
{
	delete[] score;
}

/*--- Accessors and Mutators ---*/
void ScoreDice::setScores(int a_index, Dice *dice)
{
	int i = 0;
	int t_score = 0;
	switch(a_index){
		case 0: // ones
			for(i = 0; i < MAX_DICE; i++){
				if(dice[i].getDiceValue() == 1){t_score++;}
			}
			score[a_index].score += (t_score * 100);
			score[a_index].beenScored = true;
			break;
		case 1: // two
			for(i = 0; i < MAX_DICE; i++){
				if(dice[i].getDiceValue() == 2){t_score++;}
			}
			score[a_index].score += (t_score * 200);
			score[a_index].beenScored = true;
			break;
		case 2: //three
			for(i = 0; i < MAX_DICE; i++){
				if(dice[i].getDiceValue() == 3){t_score++;}
			}
			score[a_index].score += (t_score * 300);
			score[a_index].beenScored = true;
			break;
		case 3: // four
			for(i = 0; i < MAX_DICE; i++){
				if(dice[i].getDiceValue() == 4){t_score++;}
			}
			score[a_index].score += (t_score * 400);
			score[a_index].beenScored = true;
			break;
		case 4: // fives
			for(i = 0; i < MAX_DICE; i++){
				if(dice[i].getDiceValue() == 5){t_score++;}
			}
			score[a_index].score += (t_score * 500);
			score[a_index].beenScored = true;
			break;
		case 5: // sixes
			for(i = 0; i < MAX_DICE; i++){
				if(dice[i].getDiceValue() == 6){t_score++;}
			}
			score[a_index].score += (t_score * 600);
			score[a_index].beenScored = true;
			break;
		case 6: //3 of a kind
			if(checkSpecialScores(a_index, dice)){
				score[a_index].beenScored = true;
			}
			break;
		case 7: //4 of a kind
			if(checkSpecialScores(a_index, dice)){
				score[a_index].beenScored = true;
			}
			break;
		case 8: // Full House
			if(checkSpecialScores(a_index, dice)){
				score[a_index].score = FHOUSE;
				score[a_index].beenScored = true;
			}
			break;
		case 9: // Small Straight
			if(checkSpecialScores(a_index, dice)){
				score[a_index].score = SSTRAIGHT;
				score[a_index].beenScored = true;
			}
			break;
		case 10: // Large Straight
			if(checkSpecialScores(a_index, dice)){
				score[a_index].score = LSTRAIGHT;
				score[a_index].beenScored = true;
			}
			break;
		case 11: // Omega
			for(i = 0; i < MAX_DICE; i++){
				if((i+1) != MAX_DICE){
					if(dice[i].getDiceValue() == dice[i+1].getDiceValue())
						t_score++;
				}
				else{
					if(dice[i].getDiceValue() == dice[0].getDiceValue())
						t_score++;
				}
			}
			if(t_score == MAX_DICE){
				score[a_index].score = OMEGA_SCORE;
				score[a_index].beenScored = true;
			}
			break;
		case 12: //chance
			for(i = 0; i < MAX_DICE; i++){
				t_score += dice[i].getDiceValue() * 10;
			}
			score[a_index].score = t_score;
			score[a_index].beenScored = true;
			break;
	}
}

/*--- Sub-Functions ---*/
bool ScoreDice::checkSpecialScores(int a_case, Dice * dice)
{
	int i = 0;
	int t_dice[MAX_DICE_SLOTS];
	bool t_result;
	int t_num = 0;
	bool t_checked = false;

	//initialize t_dice
	for(int h = 0; h < MAX_DICE_SLOTS; h++){
		t_dice[h] = 0;
	}
	// fill t_dice with the numbers
	for(i = 0; i < MAX_DICE; i++){
		switch(dice[i].getDiceValue())
		{
		case 1: // value 1
			t_dice[0]++;
			break;
		case 2: // value 2
			t_dice[1]++;
			break;
		case 3: // value 3
			t_dice[2]++;
			break;
		case 4: // value 4
			t_dice[3]++;
			break;
		case 5: // value 5
			t_dice[4]++;
			break;
		case 6: // value 6
			t_dice[5]++;
			break;
		}
	}

	// depending on case check if true
	switch((ScoreType)a_case)
	{
	case KIND3:  // checks for three of a kind and gives appropriate scoring
		for (i = 0; i < MAX_DICE_SLOTS; i++){
			switch(t_dice[i])
			{
			case 1:
				score[a_case].score += (i+1) * 10;
				break;
			case 2:
				score[a_case].score += (i+1) * 20;
				break;
			case 3:
				score[a_case].score += (i+1) * 30;
				break;
			}
		}
		t_result = true;
		break;
	case KIND4: // checks for 4 of a kind and gives appropriate scoring
		for (i = 0; i < MAX_DICE_SLOTS; i++){
			switch(t_dice[i])
			{
			case 1:
				score[a_case].score += (i+1) * 10;
				break;
			case 4:
				score[a_case].score += (i+1) * 40;
				break;
			}
		}
		t_result = true;
		break;
	case F_HOUSE: // checks for 3 of a kind and a pair
		bool isPair;
		bool isTriple;
		for(i = 0; i < MAX_DICE_SLOTS; i++){
			switch(t_dice[i])
			{
			case 2:
				isPair = true;
				break;
			case 3:
				isTriple = true;
				break;
			}
		}
		if(isPair && isTriple) t_result = true;
		else t_result = false;
		break;
	case S_STRAIGHT: // checks that 4 of the dice are sequential. (1-4 or 2-5 or 3-6)
		t_num = 0;
		t_checked = false;
		for(i = 0; i < MAX_DICE_SLOTS; i++){
			if(t_num != MAX_4KIND){
				switch(t_dice[i])
				{
				case 1:
					if(t_num == (MAX_4KIND-1)){
						// if the last dice in the series == 1
						// add this to the t_count
						if(t_dice[i] == 1) t_num++;
					}
					else if((i + 1) != MAX_DICE_SLOTS){
						if(t_dice[i] == t_dice[i+1]) t_num++;
						else if(t_dice[i] == t_dice[i+1]-1) t_num++;
					}
					else if(t_dice[i] == 1) t_num++;
					break;
				case 2:
					if(!t_checked){
						if(t_num == (MAX_DICE_SLOTS-1)){
							// if the last dice in the series == 1
							// add this to the t_count
							if(t_dice[i] == 1) t_num++;
						}
						else if((i+1) != MAX_DICE_SLOTS){
							if(t_dice[i]-1 == t_dice[i+1]) t_num++;
						}
						t_checked = true;
					}
					break;
				}
			}
		}
		if(t_num == MAX_4KIND) t_result = true;
		else t_result = false;
		break;
	case L_STRAIGHT: // checks that all of the dice are sequential. (1-5 or 2-6)
		t_num = 0;
		t_checked = false;
		for(i = 0; i < MAX_DICE_SLOTS; i++){
			if(t_num != MAX_STRAIGHT){
				switch(t_dice[i])
				{
				case 1:
					if(t_num == (MAX_STRAIGHT-1)){
						// if the last dice in the series == 1
						// add this to the t_count
						if(t_dice[i] == 1) t_num++;
					}
					else if((i+1) != MAX_DICE_SLOTS){
						if(t_dice[i] == t_dice[i+1]) t_num++;
					}
					break;
				case 2:
					if(!t_checked){
						if(t_num == (MAX_DICE_SLOTS-1)){
							// if the last dice in the series == 1
							// add this to the t_count
							if(t_dice[i] == 1) t_num++;
						}
						else if((i+1) != MAX_DICE_SLOTS){
							if((t_dice[i]-1) == t_dice[i+1]) t_num++;
						}
						t_checked = true;
					}
					break;
				}
			}
		}
		if(t_num == MAX_STRAIGHT) t_result = true;
		else t_result = false;
		break;
	}
	return t_result;
}

void ScoreDice::setFont(TTF_Font * a_font)
{
	font = a_font;
	text_height = TTF_FontHeight(font);
}